home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-05-16 | 15.2 KB | 430 lines | [TEXT/R*ch] |
- Mark,
-
- I just surfed to your Web page, not bad at all. (I'm based in
- mississauga ont. BTW) With Regards to ReadPNG.c. I basically added my own
- CreatePICT2 routine to use a GWorld to convert the raw pixel buffer from
- the PNG image returned in row_buf. Unfortunately it isn't working, and i'm
- not sure whether the stuff read into row_buf was wrong, or whether my
- copying of the pixel image from the PNG buffer to the Gworld buffer is
- wrong because I'm not taking into account something about the PNG image
- layout. Any suggestions would be appreciated.
-
-
-
-
- #include <stdio.h>
- #include <stdlib.h>
- #include "png.h"
-
- // Requires: libpng, zlib, ANSI (4i) C lib's
-
- #include <Files.h>
- #include <Memory.h>
-
- #define RECT_TOP(rect) (rect).top
- #define RECT_LEFT(rect) (rect).left
- #define RECT_BOTTOM(rect) (rect).bottom
- #define RECT_RIGHT(rect) (rect).right
-
- #define RECT_WIDTH(rect) (RECT_RIGHT(rect) - RECT_LEFT(rect) )
- #define RECT_HEIGHT(rect) (RECT_BOTTOM(rect) - RECT_TOP(rect) )
- #define RECT_MIDX(rect) (RECT_LEFT(rect) + (RECT_RIGHT(rect) - RECT_LEFT(rect) >> 1) )
- #define RECT_MIDY(rect) (RECT_TOP(rect) + (RECT_BOTTOM(rect) - RECT_TOP(rect) >> 1) )
-
-
- extern OSErr DumpPixMap(PixMapHandle aPixMap);
- PicHandle CreatePICT2(PixMap *pixMap,Rect *boundsRect, short mode);
- PicHandle ReadPGN(FSSpec *sfFilePtr);
-
-
- PicHandle ReadPGN(FSSpec *sfFilePtr)
- {
- OSErr err = noErr;
- short savedVol;
- Str31 name;
-
- png_struct read_ptr;
- png_info info_ptr;
- png_info end_info;
-
- FILE *fpin;
- png_byte *row_buf;
- png_uint_32 rowbytes;
- png_uint_32 y, x;
- int channels, num_pass, pass;
- PicHandle myPic = nil;
-
- BlockMoveData((Ptr)(sfFilePtr->name), (Ptr)name, sizeof(Str31));
-
- err = GetVol(0, &savedVol);
- if (err == noErr)
- {
- err = HSetVol(0, sfFilePtr->vRefNum, sfFilePtr->parID);
- if (err == noErr)
- {
- p2cstr(name);
-
- row_buf = (png_byte *)0;
-
- fpin = fopen((char *) name, "rb");
- if (!fpin)
- {
- // fprintf(STDERR, "Could not find input file %s\n", inname);
- return NULL;
- }
-
- if (setjmp(read_ptr.jmpbuf))
- {
- // fprintf(STDERR, "libpng read error\n");
- fclose(fpin);
- return NULL;
- }
-
- png_read_init(&read_ptr);
- png_info_init(&info_ptr);
- png_info_init(&end_info);
-
- png_init_io(&read_ptr, fpin);
- png_read_info(&read_ptr, &info_ptr);
-
- #if OutputInfo /* RMF */
- fprintf(STDERR, "%s, Width = %d, Height = %d, Depth = %d\n",
- inname, info_ptr.width, info_ptr.height, info_ptr.bit_depth);
- fprintf(STDERR, "Color type = %d, interlace_type = %d\n",
- info_ptr.color_type, info_ptr.interlace_type);
- #endif
-
- if ((info_ptr.color_type & 3) == PNG_COLOR_MASK_COLOR)
- channels = 3;
- else channels = 1;
-
- if (info_ptr.color_type & PNG_COLOR_MASK_ALPHA)
- channels++;
-
- rowbytes = ((info_ptr.width * info_ptr.bit_depth * channels + 7) >> 3);
- // row_buf = (png_byte *)malloc((size_t)rowbytes);
- row_buf = (png_byte *)NewPtrClear(rowbytes);
-
- if (!row_buf)
- {
- //R4L fprintf(STDERR, "no memory to allocate row buffer\n");
- png_read_destroy(&read_ptr, &info_ptr, (png_info *)0);
- fclose(fpin);
- return NULL;
- }
-
- if (info_ptr.interlace_type)
- {
- num_pass = png_set_interlace_handling(&read_ptr);
- }
- else
- {
- num_pass = 1;
- }
-
-
- for (pass = 0; pass < num_pass; pass++)
- {
- for (y = 0; y < info_ptr.height; y++)
- {
- png_read_rows(&read_ptr, &row_buf, (png_byte **)0, 1); // Read one row of image data
- }
- }
-
- png_read_end(&read_ptr, &end_info);
-
- x = info_ptr.width;
- y = info_ptr.height;
-
- if (info_ptr.bit_depth == 24)
- {
- rowbytes = (x * 4L); // Make Multiple of 4 bytes (32bit RGB image)
- }
- else
- {
-
- //RS? ByteScanLine = (((x * (unsigned long) info_ptr.bit_depth) + 7L) / 8L); /* Make Multiple of byte */
- rowbytes = (((x * (unsigned long) info_ptr.bit_depth) + 7L) / 8L); /* Make Multiple of byte */
- }
-
- // info_ptr.color_type =
- // PNG_COLOR_TYPE_PALETTE
- // PNG_COLOR_TYPE_RGB
- // PNG_COLOR_TYPE_GRAY
- // PNG_COLOR_TYPE_RGB_ALPHA
- // PNG_COLOR_TYPE_GRAY_ALPHA
-
- // Black & White Image
-
- if (info_ptr.bit_depth == 1)
- {
- BitMap theBits;
-
- theBits.baseAddr = (Ptr) row_buf; // Set up new BitMap
- theBits.rowBytes = rowbytes; // width of image
- SetRect(&(theBits.bounds), 0, 0, x, y);
-
- //R4L myPic = MakePictFromBW(&theBits);
- // create a PicHandle from B&W BitMap
-
-
- // Cleanup and Exit.
- }
- else
- {
-
- CTabHandle macCtabHandle = nil;// Color Table for 2, 4, 8 bit images
- PixMap srcBits;
-
-
- if (info_ptr.bit_depth >= 2 && info_ptr.bit_depth <= 8)
- {
- if (info_ptr.valid & PNG_INFO_PLTE)
- {
- info_ptr.palette;
- info_ptr.num_palette;
- macCtabHandle = nil; // Get the color table...
- }
- }
- // See: QuickDraw.h
- // Setup PixMap data structure:
- srcBits.baseAddr = (char *)row_buf;
- // ptr to the Pixcell data
-
- // offset to next scan line
- srcBits.rowBytes = rowbytes | 0x8000; // pixmap (4, 8, 16 or 24/32bit image)
-
- srcBits.bounds.top = 0; // encloses bitmap
- srcBits.bounds.left = 0;
- srcBits.bounds.bottom = y;
- srcBits.bounds.right = x;
- srcBits.pmVersion = 0; // pixMap version number
-
- srcBits.packType = 1; // defines packing format: 1 = direct
-
- srcBits.packSize = 0L; // length of pixel data
- srcBits.hRes = 0x480000; // 72dpi fixed point
- srcBits.vRes = 0x480000; // vert. resolution (ppi)
- srcBits.planeBytes = 0L; // offset to next plane
-
- srcBits.pmTable = macCtabHandle; // color map for this pixMap
- srcBits.pmReserved = 0;
-
- if (info_ptr.bit_depth == 24)
- { // RGB data 24bit color, no Color Table
- srcBits.pixelType = RGBDirect;
- srcBits.pixelSize = 32; // # bits in pixel
- srcBits.cmpCount = 3; // # components in pixel (R,G,B)
- srcBits.cmpSize = 8; // # bits per component (3 * 8) =
- // 24bits + 8bits pad = 32 bits
-
- }
- else
- {
-
-
- // Else: 4bit or 8bit color image
- srcBits.pixelType = 0;
- srcBits.pixelSize = info_ptr.bit_depth; // # bits in pixel
- srcBits.cmpCount = 1; // # components in pixel
- srcBits.cmpSize = info_ptr.bit_depth; // # bits per component
- }
-
-
- myPic = CreatePICT2( &srcBits, &srcBits.bounds,ditherCopy);
-
- if (srcBits.pmTable)
- DisposHandle((Handle) srcBits.pmTable); // Free Color table allocated
-
-
- }
- /*------------ */
-
- /* clean up after the read, and free any memory allocated */
- png_read_destroy(&read_ptr, &info_ptr, &end_info);
-
- /* free the structures */
- free(row_buf);
-
- fclose(fpin);
- SetVol(0, savedVol);
- return myPic;
- } // End readPNG()
-
- }
- return NULL;
- }
-
-
- PicHandle CreatePICT2(PixMap *pixMap,Rect *boundsRect, short mode)
- {
- OSErr err;
- GWorldPtr imageGWorld = NULL;
- PixMapHandle phPixMap;
- Ptr imageBaseAddr,imagePtr;
- long bytesPerRow,gworldBytesPerRow;
- CGrafPtr savePort;
- GDHandle saveDevice;
- short line,imageHeight;
-
- GetGWorld(&savePort, &saveDevice);
-
- err =
- NewGWorld(&imageGWorld,pixMap->pixelSize,boundsRect,pixMap->pmTable,NULL,0L)
- ;
-
- if (err)
- return NULL;
-
- SetGWorld(imageGWorld, NULL);
-
- phPixMap = GetGWorldPixMap(imageGWorld);
- LockPixels(phPixMap);
- imageBaseAddr = GetPixBaseAddr(phPixMap);
-
- bytesPerRow = pixMap->rowBytes & 0x3fff;
- //Bytes per Row
- gworldBytesPerRow = (**phPixMap).rowBytes & 0x3fff;
-
- imagePtr = pixMap->baseAddr;
- imageHeight = boundsRect->bottom - boundsRect->top;
-
- for (line = boundsRect->top; line < boundsRect->bottom;line++)
- {
- BlockMove(imagePtr,imageBaseAddr,bytesPerRow);
- imageBaseAddr = imageBaseAddr + gworldBytesPerRow;
- imagePtr = imagePtr + bytesPerRow;
- }
-
- SetGWorld(savePort, saveDevice);
- err = DumpPixMap(phPixMap); //Debug Purposes just
- output the pixmap to a window the size of the pixmap
- UnlockPixels(phPixMap);
- DisposeGWorld(imageGWorld);
-
- return (PicHandle)NULL;
- }
-
-
- OSErr DumpPixMap(PixMapHandle aPixMap)
- {
- WindowPtr myWind;
- Rect windowRect,pixRect;
- long finalTick;
-
-
- RGBColor white = {0xFFFF,0xFFFF,0xFFFF};
- RGBColor black = {0x0000,0x0000,0x0000};
-
- if (aPixMap == NULL)
- {
- DebugStr("\pNull Pixmap Handle in DumpPixMap");
- return memFullErr;
- }
-
- HLock((Handle)aPixMap);
- pixRect = (**aPixMap).bounds;
-
- centerRectOnMainScreen(&pixRect,&pixRect);
- InsetRect(&pixRect,2,2);
-
- myWind = NewWindow(NULL, &pixRect, "\p Pixmap", TRUE, documentProc,
- (WindowPtr)-1, FALSE, NULL);
-
- if (myWind != nil)
- {
- ShowWindow(myWind);
- }
-
- SelectWindow(myWind); // activate the "Shell Window"
- windowRect = myWind->portRect;
- InsetRect(&windowRect,1,1);
-
- RGBForeColor(&black);
- RGBBackColor(&white);
-
-
- CopyBits(*(BitMap **)aPixMap,
- &(myWind)->portBits,
- &windowRect,
- &windowRect,
- srcCopy, NULL);
-
- BeginUpdate(myWind);
- EndUpdate(myWind);
-
- Delay(60,&finalTick);
- Debugger();
- DisposeWindow(myWind);
-
- HUnlock((Handle)aPixMap);
-
- return noErr;
-
- }
-
- void centerRectOnMainScreen(Rect *theRect,Rect *resultRect)
- {
- short var1,var2;
- Rect centerRect;
- GDHandle mainDevice;
-
- mainDevice = GetMainDevice();
- centerRect = (**mainDevice).gdRect;
-
- *resultRect = *theRect;
-
- var1 = theRect->right - theRect->left;
- var2 = centerRect.right - centerRect.left;
-
- if (var1 < var2)
- {
- RECT_LEFT(*resultRect) = RECT_MIDX(centerRect) - (var1 >> 1);
- RECT_RIGHT(*resultRect) = RECT_LEFT(*resultRect) + var1;
- }
-
- var1 = theRect->bottom - theRect->top;
- var2 = centerRect.bottom - centerRect.top;
-
- if (var1 < var2)
- {
- RECT_TOP(*resultRect) = RECT_MIDY(centerRect) - (var1 >> 1);
- RECT_BOTTOM(*resultRect) = RECT_TOP(*resultRect) + var1;
- }
-
- }
-
- ,
- >
- >sorry for the problems .. I did start to write ReadPNG.c (and never got
- >back to it), I did think I have included it in the archive file...
- >
- >I was planning on finishing it and getting it to work for my external
- >translators (XTND, MacEasy Open, etc...).
- >
- >I don't know when I will have time to finish it. What problems have you
- >fixed and what problems are you having?
- >
- >If my memory is correct, I was going to manually create an offscreen pixmap
- >and color table and then call a special routine for creating PICT handles
- >that is portable and does not require color quickdraw (you could used
- >OpenPicture()... etc).
- >
- >currently no update ... but when I do get to it will send you a note. Let
- >me know If you get it working, and I will include it as an update.
- >
- >
- >> I'm trying to get a simple demo up and running that reads and
- >>displays a PNG image using your mac CW port. I tried compiling the ReadPNG
- >>file, but there are a host of problems. I've tried to fix the obvious ones,
- >>but am having problems getting the image to display properly. Did you write
- >>ReadPNG.c? Is there an updated version?
- >>
- >>Roger Smith
- >
- ><<<<->>>>|
- > Mark Fleming, http://ccsmacinfo.ccs.queensu.ca/Mark/
- > Stauffer Library, Room 011c, Computing & Comm. Services,
- > Queen's University at Kingston, Ontario, Canada, K7L 3N6
- > MarkF@post.QueensU.CA, Tel:1-613-545-2039 Fax:613-545-6798
-